feat(components): enforce per-host component feature sets for commands and rules (#100) - #427
Conversation
…s and rules Publishes <kind>.<feature> capability rows (commands.* on Claude/Cursor, rules.* on Cursor, hooks.timeout/toolMatchers on hook hosts, skills.* mirroring the Skill IR) with dated evidence, judges every command and rule frontmatter field per target at validation time (AB4907/AB4927 fail closed for explicit targets, AB4908/AB4928 omit-with-reason warnings for implicit ones), and reports omitted features on selected components in inspect. Refs #100
🦋 Changeset detectedLatest commit: 3add52b The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cc4b90eeec
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| @@ -0,0 +1,5 @@ | |||
| --- | |||
| 'agent-bundle': patch | |||
There was a problem hiding this comment.
Mark the breaking validation change as minor
Change this changeset from patch to minor: existing projects with frontmatter-bearing commands that explicitly target Cursor previously built successfully but now fail with AB4927, so this is an intentional breaking behavior change. Publishing it as a patch would expose 0.x consumers to a breaking upgrade contrary to the repository's pre-1.0 semver policy.
AGENTS.md reference: AGENTS.md:L25-L26
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Agreed — changed to minor in 7efddad. A Cursor-required command carrying frontmatter previously built and now fails AB4927, which is a breaking behavior change under the pre-1.0 policy; the summary already spells the new failure out.
… a minor (breaking) bump
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7efddad8d7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| */ | ||
| const componentCapabilities: Readonly<Record<string, CapabilityState>> = Object.freeze({ | ||
| ...pluginCapabilities, | ||
| ...compositeFeatureCapabilities(unionCapabilityStates), |
There was a problem hiding this comment.
Mark plugin skill frontmatter omitted on portable fallback
When a plugin-targeted skill declares a Claude or Codex host extension, pluginSharedDocument in config/normalize.ts selects the portable lowering because the host documents differ, and that lowering strips the host extension. Unioning all feature rows here nevertheless marks skills.hostFrontmatter as supported, so inspect reports the skill as selected without omittedFeatures even though the built composite artifact discarded the applicable host metadata. Derive this feature judgment from the shared document actually selected for the composite rather than whether any constituent host supports the feature.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 3add52b: the composite now publishes skills.hostFrontmatter and skills.markdownTokens as explicit unavailable rows (in both capabilities and componentCapabilities) with the reason that its shared skills/ tree lowers any skill with a host extension or token to the portable document (pluginSharedDocument), instead of unioning the host halves. Pinned by the extended 'reports omitted component features…' api test: a skill with targets.claude.model reports no omission on Claude, omittedFeatures: [hostFrontmatter] on plugin, and the plugin host document has no model field; adapter-capability-states asserts both composite rows. Documented in the feature-set section of docs/framework-mode.md.
…ntmatter or Markdown tokens
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
#428) Document the user-facing behaviour that landed on main after the docsite PR (#384) merged, in both locales: - install: `agent-bundle install cursor --mode local|marketplace` and the Doctor findings for Cursor hook registration and marketplace staging (AB7322-AB7324) (#414) - project structure: per-host feature sets for src/commands and src/rules, with AB4907/AB4908 and AB4927/AB4928 (#427) - testing: the script-dispatch and workbench-surface proof levels, eleven in all, and the routed cli-tool template (#398) - notices reference: inbox and resources/updated wiring gated on the host's noticeDelivery advertisement (#412, #376)
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Review-status tracking (final sweep, 2026-09-03 16:37 UTC): |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Summary
Closes the "component feature sets" item from the #100 remaining-scope comment (2026-09-03), following the closed per-host Skill IR schema pattern from #108 rather than a second mechanism.
<kind capability>.<feature>four-state row per feature a component kind may use (shared helpersfeatureCapabilitiesFrom/frontmatterFeatureCapabilitiesFrom/featureCapabilityName):commands.{description,argumentHint,allowedTools,model,disableModelInvocation}— Claudesupported(plugin.commandFrontmatter, the five documented kebab-case fields the lowering regenerates); Cursorunavailablewith dated evidence that its commands surface is frontmatter-free Markdown (the 2026-09-03 commands docs URL now resolves to Skills and documents no command frontmatter). Codex/portable publish none (no commands kind).rules.{description,globs,alwaysApply}— Cursorsupported(plugin.ruleFrontmatter, retrieved 2026-09-03 from https://cursor.com/docs/context/rules).hooks.{timeout,toolMatchers}— Claude/Codex from newhooks.featuresblocks citing the pinned hooks schemas; Cursor reuses the Refresh Cursor plugin contract coverage against current public docs #189hooks.options.{timeout,matcher}rows.skills.{hostFrontmatter,markdownTokens}— mirrors the Skill IR: typed host frontmatter on Claude/Cursor/Codex (sidecar), portableunavailable; Markdown tokens Claude only, othersunavailablecitingAB3008.plugin: intersection incapabilities, union incomponentCapabilities(it emits Claude-format commands and Cursor rules).config/validate.ts, commands and rules): every frontmatter field is judged against the target's row using the component-emission judgment (componentCapabilityState), only where the kind itself is supported. Author-required target → errorAB4927(commands) /AB4907(rules); implicitly selected target → the component still ships minus the feature andvalidatereports a warningAB4928/AB4908with the host's reason. Documented indocs/diagnostics.md.omittedFeatures: [{ feature, capability }]; humaninspectprints<kind> <name> omits <feature>: <row> <state> — <reason>. Hooks reporttimeout/toolMatchersfeatures; skills reporthostFrontmatter/markdownTokens.docs/framework-mode.md"Component feature sets" subsection + matrix;docs/entry-conventions.md. Changesetagent-bundlepatch. adapterRevision: claude 1.24.0, codex 1.11.0, cursor 1.11.0, portable 1.8.0, plugin 1.27.0.Deliberate behavior change: a command that explicitly
targets: [cursor]may no longer carrydescription(or any other frontmatter field) — Cursor cannot express it, so per the fail-closed rule it isAB4927. Two test fixtures were updated accordingly; no example ships commands. If the Cursor lane (#189) later pins evidence that Cursor commands tolerate frontmatter, flippingplugin.commandFrontmatter.statein the table is the only change needed.Evidence
tests/command-config.test.ts"enforces command feature sets…": explicit Cursor target → twoAB4927errors (argumentHint, description) with the frontmatter-free reason; implicit claude+cursor+codex → twoAB4928warnings on cursor only; Claude-only andplugin-only → silent.tests/rule-config.test.ts"judges rule frontmatter features…": all three.mdcfields supported on Cursor (no diagnostics across all five targets); a synthetic host withrulesbut no field rows → threeAB4908warnings (missing-row reason) / threeAB4907errors when explicit.tests/adapter-capability-states.test.ts"publishes dated component feature rows per kind and host": every row above, composite intersection vs union, dated evidence prefixes.tests/api.test.ts"reports omitted component features per target…": Cursor command carries twoomittedFeatures; Claude/plugin commands, Cursor/plugin rules, and hooks on every host carry none;validateyields exactly the twoAB4928.tests/cli.test.ts: humancommand deploy omits argumentHint: commands.argumentHint unavailable — …frontmatter-free…line.pnpm typecheck0 errors,pnpm lint0/0, targeted unit files 132/132, integration files (api, cli, plugin-bundle, host-adapters, cursor-adapter) 342/342; earlier full runs ofpnpm test:unit(only the pre-existingnative-claude-contract5 s timeout wobble, reproduced on clean main),pnpm test:route-unit38/38,pnpm test:projection66/66.Test plan
@codex reviewon headReview status
Automated reviewer (chatgpt-codex-connector) covered
cc4b90e(one thread, fixed) and7efddad(one thread, fixed); both threads are answered. It returned "usage limits reached" for the current head3add52b73(thefix(plugin): the composite's shared skills tree cannot carry host frontmatter or Markdown tokenscommit: compositeskills.*rows, api/capability tests, one docs paragraph), so that commit is unreviewed; merged on CI green per the amended lane rule. Request@codex reviewon a follow-up when credits return.